#!/bin/bash
export LANG="zh_CN.UTF-8"

# 脚本版本
VERSION="1.1.0"

# 获取脚本所在目录
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"

# 加载配置（如果存在配置文件）
CONFIG_FILE="$SCRIPT_DIR/startup.config"
if [ -f "$CONFIG_FILE" ]; then
    source "$CONFIG_FILE"
fi

# 默认配置
: ${projectChineseName:="深度搜索项目"}
: ${projectPath:="/data/deepseek"}
: ${springBootJar:="deepseek-api-0.0.1-SNAPSHOT.jar"}
: ${jdkPath:="/data/tools/jdk-17.0.10/bin"}
: ${logFileName:="log.log"}
: ${javaOpts:="-Dfile.encoding=UTF-8"}
: ${gracefulShutdownTimeout:=10} # 优雅停机超时时间(秒)

# 定义颜色
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[0;33m'
NC='\033[0m' # 恢复默认颜色

# 输出带时间戳的日志
log() {
    local level=$1
    local message=$2
    local timestamp=$(date "+%Y-%m-%d %H:%M:%S")
    
    case "$level" in
        "INFO")
            echo -e "${GREEN}[INFO]${NC} $timestamp - $projectChineseName - $message"
            ;;
        "WARN")
            echo -e "${YELLOW}[WARN]${NC} $timestamp - $projectChineseName - $message"
            ;;
        "ERROR")
            echo -e "${RED}[ERROR]${NC} $timestamp - $projectChineseName - $message"
            ;;
        *)
            echo -e "$timestamp - $projectChineseName - $message"
            ;;
    esac
}

# 检查环境
check_environment() {
    # 检查项目路径是否存在
    if [ ! -d "$projectPath" ]; then
        log "ERROR" "项目路径 $projectPath 不存在"
        exit 1
    fi
    
    # 检查JAR文件是否存在
    if [ ! -f "$projectPath/$springBootJar" ]; then
        log "ERROR" "JAR文件 $projectPath/$springBootJar 不存在"
        exit 1
    fi
    
    # 检查JDK路径
    if [ ! -f "$jdkPath/java" ]; then
        log "ERROR" "JDK路径 $jdkPath/java 不存在或不可执行"
        exit 1
    fi
}

# 查找正在运行的程序的PID
find_process() {
    local keyword="$projectPath/$springBootJar"
    ps -ef | grep "$keyword" | grep -v grep | awk '{print $2}'
}

# 停止进程
stop_process() {
    local pids=$(find_process)
    if [ -n "$pids" ]; then
        log "INFO" "找到正在运行的进程，PID为: $pids。正在停止它们..."
        for pid in $pids; do
            # 尝试优雅停机
            log "INFO" "正在尝试优雅停止PID为 $pid 的进程..."
            kill -15 $pid
            
            # 等待进程结束，最多等待$gracefulShutdownTimeout秒
            local count=0
            while [ $count -lt $gracefulShutdownTimeout ] && kill -0 $pid 2>/dev/null; do
                sleep 1
                ((count++))
            done
            
            # 如果进程仍然存在，则强制终止
            if kill -0 $pid 2>/dev/null; then
                log "WARN" "优雅停止超时，正在强制终止PID为 $pid 的进程..."
                if kill -9 $pid 2>/dev/null; then
                    log "INFO" "PID为 $pid 的进程已强制停止。"
                else
                    log "ERROR" "停止PID为 $pid 的进程失败。"
                    return 1
                fi
            else
                log "INFO" "PID为 $pid 的进程已优雅停止。"
            fi
        done
    else
        log "INFO" "未找到正在运行的进程。"
    fi
    return 0
}

# 启动程序
start_process() {
    log "INFO" "正在启动 $projectChineseName..."
    cd "$projectPath" || { log "ERROR" "无法进入项目目录"; exit 1; }
    
    # 启动新的程序
    nohup $jdkPath/java $javaOpts -jar "$springBootJar" --logging.file.name=$logFileName $appArgs > /dev/null 2>&1 &
    local new_pid=$!
    
    # 检查进程是否成功启动
    sleep 2
    if ps -p $new_pid > /dev/null; then
        log "INFO" "新进程已成功启动，PID为: $new_pid"
    else
        log "ERROR" "启动新进程失败。"
        return 1
    fi
    
    # 等待几秒，确保应用正常启动
    sleep ${startupWaitTime:-3}
    
    # 如果配置了健康检查，则执行健康检查
    if [ "${enableHealthCheck:-false}" = "true" ] && command -v curl >/dev/null 2>&1; then
        log "INFO" "正在进行健康检查..."
        local timeout=0
        while [ $timeout -lt ${healthCheckTimeout:-30} ]; do
            if curl -s -f "$healthCheckUrl" >/dev/null 2>&1; then
                log "INFO" "健康检查通过，应用已成功启动"
                break
            fi
            log "WARN" "应用尚未就绪，等待 ${healthCheckInterval:-5} 秒后重试..."
            sleep ${healthCheckInterval:-5}
            timeout=$((timeout + healthCheckInterval))
        done
        
        if [ $timeout -ge ${healthCheckTimeout:-30} ]; then
            log "WARN" "健康检查超时，应用可能未成功启动，请检查日志"
        fi
    fi
    
    return 0
}

# 查看程序状态
check_status() {
    local pids=$(find_process)
    if [ -n "$pids" ]; then
        log "INFO" "程序正在运行，PID为: $pids"
        return 0
    else
        log "INFO" "程序未运行"
        return 1
    fi
}

# 显示帮助信息
show_help() {
    echo "用法: $0 [选项]"
    echo "选项:"
    echo "  start    启动程序"
    echo "  stop     停止程序"
    echo "  restart  重启程序"
    echo "  status   检查程序运行状态"
    echo "  log      查看日志"
    echo "  help     显示帮助信息"
    echo "  version  显示版本信息"
    echo "如果不带参数运行，默认执行重启操作"
}

# 显示版本信息
show_version() {
    echo "$projectChineseName 管理脚本 v$VERSION"
}

# 查看日志
view_log() {
    if [ ! -f "$projectPath/$logFileName" ]; then
        log "WARN" "日志文件不存在: $projectPath/$logFileName"
        return 1
    fi
    
    log "INFO" "正在查看日志 $projectPath/$logFileName，按Ctrl+C退出..."
    tail -f "$projectPath/$logFileName"
}

# 主函数
main() {
    case "$1" in
        start)
            check_environment
            check_status >/dev/null && { log "WARN" "程序已在运行中，请先停止"; exit 1; }
            start_process
            # 根据配置决定是否自动查看日志
            [ "${autoViewLog:-true}" = "true" ] && view_log
            ;;
        stop)
            stop_process
            ;;
        restart)
            stop_process
            check_environment
            start_process
            # 根据配置决定是否自动查看日志
            [ "${autoViewLog:-true}" = "true" ] && view_log
            ;;
        status)
            check_status
            ;;
        log)
            view_log
            ;;
        help)
            show_help
            ;;
        version)
            show_version
            ;;
        "")
            # 默认操作：重启
            stop_process
            check_environment
            start_process
            # 根据配置决定是否自动查看日志
            [ "${autoViewLog:-true}" = "true" ] && view_log
            ;;
        *)
            log "ERROR" "未知选项: $1"
            show_help
            exit 1
            ;;
    esac
}

# 执行主函数
main "$@"